REPORT ZBATCHINPUT.
* -------------------------------------------------------------------- *
* En este programa se utiliza la transacción FB09 (modificar posición de
* documento) para ejemplificar el uso del Batch-Input y del Call-
* Transaction.
************************************************************************
*                            BATCH-INPUT                               *
************************************************************************
* En el juego de datos se introduce un campo que no existe (BSEG-ABCDE);
* sin embargo, este error no detiene el proceso cuando se ejecuta el
* batch-input aunque sí se refleja en el log. Sin embargo en un call-
* transaction sí se considera un error y no se actualiza esa transacción
* -------------------------------------------------------------------- *
*                        Resultado on-line                             *
* -------------------------------------------------------------------- *
* Se produce un JD. Éste contiene una transacción errónea, la primera.
* En el momento de procesar el JD podemos corregir la transacción o bien
* pasar a la siguiente (Sistema/Servicios/Batch_inp/Transacc.siguiente)
* en cuyo caso esta transacción quedará en el JD en el apartado de
* 'JD erróneos'.
* -------------------------------------------------------------------- *
*                      Resultado en background                         *
* -------------------------------------------------------------------- *
* Es el mismo que on-line.
*
************************************************************************
*                           CALL-TRANSACTION                           *
************************************************************************
* En un Call Transaction las transacciones correctas se actualizan, las
* erróneas no.
* Hay que lanzar un Call Transaction por cada registro de la tabla.
* El modo de actualización puede ser A(Asíncrono) S(Síncrono) y L(Local)
* Si el programa se lanza en fondo da igual el MODE ('A', 'E' o 'N') del
* Call-Transaction; en este caso, si se quiere ver una orden SPOOL con
* los errores es necesario hacer el LOOP sobre la tabla de los errores
* y escribirlos con WRITE.
* Se habilita un procedimiento para guardar en un juego de datos las
* transacciones (registros) incorrectas. Esto es muy útil si el CALL
* TRANSACTION tiene lugar en un job de fondo donde no se permite el
* procesamiento on-line de las transacciones incorrectas.
* -------------------------------------------------------------------- *
*                        Resultado on-line                             *
* -------------------------------------------------------------------- *
* El proceso depende del modo de visualización escogido.
* A: se procesan on-line todas las transacciones.
* E: sólo se procesan on-line las transacciones erróneas.
* N: no hay procesamiento on-line.
* Las transacc.incorrectas se pierden, salvo que se hayan corregido on-
* line. En el modo 'N' estas transacc. se pierden irremediablemente.
* Para evitar perder las transacc.erróneas éstas pueden almacenarse en
* un JD para procesarlas posteriormente on-line. Esto es lo que se ha
* hecho en este programa.
* -------------------------------------------------------------------- *
*                      Resultado en background                         *
* -------------------------------------------------------------------- *
* Independientemente del modo de visualización (A, E ó N), las transacc.
* correctas se actualizan en el sistema y las incorrectas se pierden
* salvo que se hayan guardado en un JD.
* El resultado es similar al on-line.
*
*
* -------------------------------------------------------------------- *
* Tanto si es batch-input como call-transaction, se tiene que limpiar la
* tabla BDCTAB al comienzo de cada transacción, sino se van acumulando
* las transacciones y siempre se ejecutaría la primera.
* -------------------------------------------------------------------- *
*
************************************************************************
*                           DIRECT INPUT                               *
************************************************************************
* Sólo está permitido para los programas estándar de transferencia de
* datos (ver transacción SXDA).
TABLES:
  BGR00,
  BBKPF,
  BBSEG.

CONSTANTS:
  CODE LIKE TSTC-TCODE VALUE 'FB09',
  FICHERO_SALIDA LIKE FILEINFO-NAME VALUE '/tmp/roman_tmp/dir_inp.txt',
  CTE_NODATA LIKE BGR00-NODATA VALUE '#'.

DATA:
  MENSAJE LIKE T100-TEXT,
  STR_TMP(255).

DATA:
  BEGIN OF ITAB OCCURS 0,
    BELNR LIKE BKPF-BELNR,
    BUKRS LIKE BKPF-BUKRS,
    GJAHR LIKE BKPF-GJAHR,
    ZUONR LIKE BSEG-ZUONR,
    SGTXT LIKE BSEG-SGTXT,
  END OF ITAB,
  BDC_TAB LIKE STANDARD TABLE OF BDCDATA WITH HEADER LINE,
  ERR_BI  LIKE STANDARD TABLE OF BDCMSGCOLL WITH HEADER LINE.


************************************************************************
*                          START-OF-SELECTION                          *
************************************************************************
START-OF-SELECTION.

* Llenado de la tabla interna con los datos
PERFORM FILL_ITAB.
*======================================================================*
*                             Batch-Input                              *
*======================================================================*
PERFORM BATCHINPUT.
*======================================================================*
*                          Call Transaction                            *
*======================================================================*
PERFORM CALLTRANSACTION.
*======================================================================*
*                            Direct Input                              *
*======================================================================*
PERFORM DIRECTINPUT.


************************************************************************
*                           END-OF-SELECTION                           *
************************************************************************
END-OF-SELECTION.

*&---------------------------------------------------------------------*
*&      Form  DYNPRO
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM DYNPRO USING    VALUE(DYNBEGIN)
                     VALUE(NAME)
                     VALUE(VALUE).

  CLEAR BDC_TAB.
  IF DYNBEGIN = 'X'.
     BDC_TAB-PROGRAM  = NAME.
     BDC_TAB-DYNPRO   = VALUE.
     BDC_TAB-DYNBEGIN = 'X'.
  ELSE.
     BDC_TAB-FNAM = NAME.
     BDC_TAB-FVAL = VALUE.
  ENDIF.
  APPEND BDC_TAB.
  CLEAR BDC_TAB.

ENDFORM.                    " DYNPRO

*&---------------------------------------------------------------------*
*&      Form  BDC_OPEN
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM BDC_OPEN.

  CALL FUNCTION 'BDC_OPEN_GROUP'
       EXPORTING
            CLIENT              = SY-MANDT
            GROUP               = 'Pruebas'
            KEEP                = 'X'
            USER                = SY-UNAME.

ENDFORM.                    " BDC_OPEN

*&---------------------------------------------------------------------*
*&      Form  BDC_INSERT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM BDC_INSERT.

  CALL FUNCTION 'BDC_INSERT'
       EXPORTING
            TCODE            = CODE
       TABLES
            DYNPROTAB        = BDC_TAB.

ENDFORM.                    " BDC_INSERT

*&---------------------------------------------------------------------*
*&      Form  BDC_CLOSED
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM BDC_CLOSED.

  CALL FUNCTION 'BDC_CLOSE_GROUP'
       EXCEPTIONS
            NOT_OPEN    = 1
            QUEUE_ERROR = 2
            OTHERS      = 3.

ENDFORM.                    " BDC_CLOSED

*&---------------------------------------------------------------------*
*&      Form  FILL_ITAB
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM FILL_ITAB.
  MOVE:
    '9900000001' TO ITAB-BELNR,
    'TEL1'       TO ITAB-BUKRS,
    '2000'       TO ITAB-GJAHR,
    'Texto9 !!!' TO ITAB-ZUONR,
    '=AC'        TO ITAB-SGTXT.
  APPEND ITAB.
  MOVE:
    '1900000002' TO ITAB-BELNR,
    'TEL1'       TO ITAB-BUKRS,
    '2000'       TO ITAB-GJAHR,
    'Texto9 !!!' TO ITAB-ZUONR,
    '=VI'        TO ITAB-SGTXT.
  APPEND ITAB.
  MOVE:
    '1900000003' TO ITAB-BELNR,
    'TEL1'       TO ITAB-BUKRS,
    '2000'       TO ITAB-GJAHR,
    'Texto9 !!!' TO ITAB-ZUONR,
    '=GU'        TO ITAB-SGTXT.
  APPEND ITAB.

ENDFORM.                    " FILL_ITAB

*&---------------------------------------------------------------------*
*&      Form  BATCHINPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM BATCHINPUT.

  LOOP AT ITAB.
    REFRESH BDC_TAB. " ------------------ Borrar la transacción anterior

    AT FIRST.
     PERFORM BDC_OPEN. " ------------------- Apertura del juego de datos
    ENDAT.

    REFRESH BDC_TAB. "<------------------ Borrar la transacción anterior
    PERFORM DYNPRO USING:
                           'X' 'SAPMF05L'    '0102',
                           ' ' 'RF05L-BELNR' ITAB-BELNR,
                           ' ' 'RF05L-BUKRS' ITAB-BUKRS,
                           ' ' 'RF05L-GJAHR' ITAB-GJAHR,
                           ' ' 'RF05L-XKSAK' 'X',
                           ' ' 'BDC_OKCODE'  '/00',
                           'X' 'SAPMF05L'    '0300',
                           ' ' 'BSEG-ABCDE'  '21022000', " No existe !!!
                           ' ' 'BSEG-ZUONR'  ITAB-ZUONR,
                           ' ' 'BSEG-SGTXT'  ITAB-SGTXT,
                           ' ' 'BDC_OKCODE'  'AE',
                           'X' 'SAPLKACB'    '0002',
                           ' ' 'BDC_OKCODE'  'ENTE'.
*   Adición de la transacción a la tabla del juego de datos. Se añade
*   una transacción por cada registro de datos de ITAB.
    PERFORM BDC_INSERT. " --------------- Inserción en el juego de datos

    AT LAST.
     PERFORM BDC_CLOSED. " ------------------- Cierre del juego de datos
    ENDAT.

  ENDLOOP.

ENDFORM.                    " BATCHINPUT

*&---------------------------------------------------------------------*
*&      Form  CALLTRANSACTION
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM CALLTRANSACTION.
  DATA COPY_SYTABIX LIKE SY-TABIX.

  LOOP AT ITAB.
    MOVE SY-TABIX TO COPY_SYTABIX.

*   Apertura de un JD para las transacciones erróneas
    AT FIRST.
      PERFORM BDC_OPEN.
    ENDAT.

*   Proceso de cada registro de ITAB (cada registro es una transacción)
    REFRESH BDC_TAB. "<------------------ Borrar la transacción anterior
    PERFORM DYNPRO USING:
                           'X' 'SAPMF05L'    '0102',
                           ' ' 'RF05L-BELNR' ITAB-BELNR,
                           ' ' 'RF05L-BUKRS' ITAB-BUKRS,
                           ' ' 'RF05L-GJAHR' ITAB-GJAHR,
                           ' ' 'RF05L-XKSAK' 'X',
                           ' ' 'BDC_OKCODE'  '/00',
                           'X' 'SAPMF05L'    '0300',
*                          ' ' 'BSEG-ABCDE'  '21022000', " No existe !!!
                           ' ' 'BSEG-ZUONR'  ITAB-ZUONR,
                           ' ' 'BSEG-SGTXT'  ITAB-SGTXT,
                           ' ' 'BDC_OKCODE'  'AE',
                           'X' 'SAPLKACB'    '0002',
                           ' ' 'BDC_OKCODE'  'ENTE'.
*   Escribimos los mensajes de cada transacción para que salgan agrupa-
*   dos con el mensaje de 'sin errores' o 'con errores' de su transacc.
*   correspondiente. Para ello es necesario limpiar la tabla ERR_BI en
*   cada transacción ya que el sistema no la limpia cuando llama a la
*   transacción.
    REFRESH ERR_BI.
    CALL TRANSACTION 'FB09' USING BDC_TAB MODE 'A' MESSAGES INTO ERR_BI.
    NEW-LINE.
    IF SY-SUBRC = 0.
      WRITE:'Transacción', COPY_SYTABIX LEFT-JUSTIFIED, ': sin errores'.
    ELSE.
      WRITE:'Transacción', COPY_SYTABIX LEFT-JUSTIFIED, ': con errores'.
*     Adición de la transacción errónea al JD para procesarlo on-line
*      PERFORM BDC_INSERT.
    ENDIF.
*   ERR_BI va acumulando todos los errores que se van produciendo en las
*   transacciones (no la limpia el sistema en cada transacción).
    LOOP AT ERR_BI.
      SELECT SINGLE TEXT INTO MENSAJE
                         FROM T100
                        WHERE SPRSL = 'S'          AND
                              ARBGB = ERR_BI-MSGID AND
                              MSGNR = ERR_BI-MSGNR.
      NEW-LINE.
      WRITE AT: 1 ERR_BI-DYNAME,
               15 ERR_BI-DYNUMB,
               20 ERR_BI-MSGTYP,
               22 ERR_BI-MSGNR,
               26 MENSAJE.
************************************************************************
*     Con las siguientes líneas de código podemos concatenar todas     *
*     las variables del mensaje en el cuerpo del mensaje.              *
*----------------------------------------------------------------------*
*     DATA: MENSAJE1 ... MENSAJE4 LIKE MENSAJE.
*     SPLIT MENSAJE AT '&' INTO MENSAJE1 MENSAJE2 MENSAJE3 MENSAJE4.
*     CONCATENATE MENSAJE1 ERR_BI-MSGV1 MENSAJE2 ERR_BI-MSGV2
*                 MENSAJE3 ERR_BI-MSGV3 MENSAJE4 ERR_BI-MSGV4
*                 INTO MENSAJE SEPARATED BY SPACE.
*     WRITE MENSAJE.
************************************************************************

    ENDLOOP.

*   Cierre del JD abierto para los errores. Hay que colocarlo al final
*   pues si lo colocamos después del AT FIRST y por lo tanto antes del
*   cuerpo del LOOP, si la tabla interna sólo tiene un registro el AT
*   LAST se procesa en el mismo bucle e inmediatamente después del AT
*   FIRST por lo que inmediatamente después de abrir el JD éste se es
*   cerrado. Si ocurriera que ese registro fuera erróneo, al pretender
*   hacer el INSERT al JD ocurriría un error ya que el JD se cerró.
    AT LAST.
      PERFORM BDC_CLOSED.
    ENDAT.

  ENDLOOP."<--------------------------- Siguiente transacción (registro)

ENDFORM.                    " CALLTRANSACTION

*&---------------------------------------------------------------------*
*&      Form  DIRECTINPUT
*&---------------------------------------------------------------------*
* Para hacer un Direct Input usaremos el programa estándar de transf. de
* datos RFBIBL00.
*----------------------------------------------------------------------*
FORM DIRECTINPUT.

  PERFORM CREATEFILE.
  PERFORM RUN_RFBIBL00.

ENDFORM.                    " DIRECTINPUT

*&---------------------------------------------------------------------*
*&      Form  CREATEFILE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM CREATEFILE.

  DATA: NAME_JD LIKE BGR00-GROUP VALUE 'JD_DIR_INPUT'.
  OPEN DATASET FICHERO_SALIDA FOR OUTPUT IN TEXT MODE.
  PERFORM REC_NODATA USING BGR00.
  MOVE:
    '0'        TO BGR00-STYPE,
    NAME_JD    TO BGR00-GROUP,
    SY-MANDT   TO BGR00-MANDT,
    SY-UNAME   TO BGR00-USNAM,
    'X'        TO BGR00-XKEEP.
  TRANSFER BGR00 TO FICHERO_SALIDA.
  PERFORM REC_NODATA USING BBKPF.
  MOVE:
    '1'        TO BBKPF-STYPE,
    'FB01'     TO BBKPF-TCODE,
    'TEL1'     TO BBKPF-BUKRS,
    '03032000' TO BBKPF-BLDAT,
    'KR'       TO BBKPF-BLART,
    'ESP'      TO BBKPF-WAERS,
    'ABCDE'    TO BBKPF-XBLNR,
    'X'        TO BBKPF-XMWST.
  TRANSFER BBKPF TO FICHERO_SALIDA.
  PERFORM REC_NODATA USING BBSEG.
  MOVE:
    '2'          TO BBSEG-STYPE,
    'BBSEG'      TO BBSEG-TBNAM,
    '31'         TO BBSEG-NEWBS,
    '2000000014' TO BBSEG-NEWKO,
    '85000'      TO BBSEG-WRBTR,
    '1D'         TO BBSEG-MWSKZ,
    'BSIT'       TO BBSEG-HBKID.
  TRANSFER BBSEG TO FICHERO_SALIDA.
  PERFORM REC_NODATA USING BBSEG.
  MOVE:
    '2'          TO BBSEG-STYPE,
    'BBSEG'      TO BBSEG-TBNAM,
    '40'         TO BBSEG-NEWBS,
    '6000000'    TO BBSEG-NEWKO,
    '85000'      TO BBSEG-WRBTR,
    'ZTEL100001' TO BBSEG-KOSTL,
    '=AC'        TO BBSEG-SGTXT.
  TRANSFER BBSEG TO FICHERO_SALIDA.
  CLOSE DATASET FICHERO_SALIDA.

ENDFORM.                    " CREATEFILE

*&---------------------------------------------------------------------*
*&      Form  REC_NODATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM REC_NODATA USING    REC_NAME.

  DATA: COPY_SYSUBRC LIKE SY-SUBRC.
  FIELD-SYMBOLS: .

  WHILE COPY_SYSUBRC EQ 0.
    ASSIGN COMPONENT SY-INDEX OF STRUCTURE REC_NAME TO .
    MOVE SY-SUBRC TO COPY_SYSUBRC.
    CHECK SY-SUBRC EQ 0.
    MOVE CTE_NODATA TO .
  ENDWHILE.

ENDFORM.                    " REC_NODATA

*&---------------------------------------------------------------------*
*&      Form  RUN_RFBIBL00
*&---------------------------------------------------------------------*
* Si se emplea el CALLMODE = 'D' (Direct Input) hay algunas operaciones
* que no se admiten (como el cálculo automático de impuestos) y darían
* lugar a errores.
* -------------------------------------------------------------------- *
*                        Resultado on-line                             *
* -------------------------------------------------------------------- *
* El programa creará un JD con las transacc.erróneas si así ha sido
* implementado en su código. El RFBIBL00 crea un JD con los errores en
* los CALLMODE 'C' y 'D'. En el 'B' crea un JD con todas las transacc.
* -------------------------------------------------------------------- *
*                      Resultado en background                         *
* -------------------------------------------------------------------- *
* El resultado depende del CALLMODE
* B: Se crea el JD.
* C: Ocurre un error si el job que lanza el ZBORRAR14 no es reiniciable.
* D: Ocurre un error si el job que lanza el ZBORRAR14 no es reiniciable.
* Si el job es reiniciable se crea un JD con las transacc.erróneas tanto
* en modo 'C' como en 'D'.
* Para crear un job reiniciable:
* Transacc.BMV0/Ejecutar-->Definición de job.
* Escribir el nombre del job que lanza a el ZBORRAR14.
*----------------------------------------------------------------------*
FORM RUN_RFBIBL00.

  SUBMIT RFBIBL00 WITH  DS_NAME = FICHERO_SALIDA
                  WITH CALLMODE = 'D' AND RETURN.

ENDFORM.                    " RUN_RFBIBL00